home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / POLYCOLL.ZIP / POLYCOLL.TXT next >
Encoding:
Text File  |  1996-10-16  |  7.6 KB  |  142 lines

  1. Collision point of two non-rotating polygons
  2.  
  3. A couple of threads recently on Compuserve have dealt with how to determine 
  4. when two non-rotating polygon objects collide.  Below is a short discussion of 
  5. one algorithm to determine when and where the collision happens.  The algorithm 
  6. will work for both convex and concave figures with any number of line 
  7. segments.  The algorithm works entirely by intersecting lines, and thus does 
  8. not rely on time-consuming iterative methods.  One special case we need to 
  9. handle is when we compare two line segments which are parallel or 
  10. nearly-parallel.  Finally, the algorithm works even for objects that pass 
  11. completely through each other in the course of one frame.
  12.  
  13. I don't get into rotating polygons, transfering momentum between the objects 
  14. (see collid.zip for ball collisions.  Much of that info will apply to this 
  15. as long as the objects are nearly circular,) accelerations during the frame, 
  16. nor multiple collisions within one frame of action.
  17.  
  18. The trick to making this simple and quick is to recognize that the "point of 
  19. intersection" between the two line segments changes over the course of the 
  20. frame.  The path of the point of intersection describes a line.  Intersect 
  21. that line with the line described by the path of one of the endpoints and you 
  22. have a possible collision point.  This is fairly difficult to explain in 
  23. words, but the figures included in this zip file will help you visualize 
  24. what's happening.
  25.  
  26. Prior to Figure 1 you'll want to perform some bounding box tests to cull out 
  27. most of the line segments on the screen.  First, you'll want to test each 
  28. object against each other object.  Be sure to include the full extents of the 
  29. objects motion for the current frame.  Next, for any object pairs which pass 
  30. that test you'll want to test each line segement in one object with each line 
  31. segment in the other object. In most situations you'll probably be down to a 
  32. very few lines to compare.
  33.  
  34. Figure 1 shows two objects and their velocity vectors.  Figure 2 highlights 
  35. one line segment on each object.
  36.  
  37. In Figure 3, we've extended the line segments indefinately in each direction.  
  38. This gives us our initial point of intersection.
  39.  
  40. In Figure 4, we've moved the line segments to their position at the end of the 
  41. frame and again extended the lines.  This time we get the final point of 
  42. intersection. Over the course of the frame, the path of this point of 
  43. intersection will describe a line from the initial to the final point.
  44.  
  45. In Figure 5, we've shown the path of the endpoints and where they intersect 
  46. with path of intersection.  We end up with four possible points of collision.  
  47. At this point, you probably want to sort the four points by distance to the 
  48. initial initial point of intersection.  The closest happens earliest in the 
  49. frame (neglecting acceleration.)
  50.  
  51. In Figure 6, we've determined that Point 1 lies outside of the blue line 
  52. segment.  The easiest way to determine this is to calculate the distance from 
  53. Point 1 to each of the endpoints of the blue line segment.  If either distance 
  54. is greater than the length of the blue line segment then the point lies 
  55. outside the line segment.
  56.  
  57. In Figure 7, we've determined that Point 2 does lie within the red line 
  58. segment.  This is our point of impact.  The distance along the path of 
  59. intersection is proportional to the time within the frame when the collision 
  60. occurred.  IOW, in Figure 7, Point 2 appears to lie just about halfway from 
  61. the Initial point to the Final point.  Therefore, the collision happened 
  62. halfway through the frame (again, neglecting acceleration.)
  63.  
  64. That's all there is to it.  The figures make it pretty straightforward.
  65.  
  66. You may remember that I mentioned a special case.  If the line segments in 
  67. question are parallel then you won't have a path of intersection to play with.  
  68. Instead, the lines containing the line segments will overlap at only one 
  69. instant during the frame.
  70.  
  71. Another, problem arises if the lines are nearly parallel.  In that case, the 
  72. Initial and Final points of intersection may be so far away that you risk 
  73. overflowing your variables.  I suggest that you treat nearly parallel lines as 
  74. parallel and perform the following special case algorithm.
  75.  
  76. The trick for parallel lines is to recognize that the fact that they're 
  77. parallel in effect removes one dimension from the problem.  We've gone from a 
  78. two-dimensional system with intersection lines to a one-dimensional system 
  79. where two lines are closing on each other.
  80.  
  81. Actually, they may not be headed directly at each other, as shown in Figure 8.  
  82. But, since the lines are known to be parallel, then the velocity vector 
  83. perpendicular to the line's slope is by definition the closing speed relative 
  84. to the other line segment.  These are the dotted lines in Figure 9.  Once we 
  85. know these closing speeds, the problem becomes a simple one-dimensional 
  86. rate-distance problem.
  87.  
  88.   rate1 * t + rate2 * t = distance
  89.   t = distance / (rate1 + rate2)
  90.  
  91. Once you've calculate t you need to test the line segments to verify that they 
  92. have in fact overlapped.  Take one endpoint from the red line segment and 
  93. calculate the distance to both endpoints of the blue line segment.  If the 
  94. distance to both is less than the length of the blue line segment then the red 
  95. endpoint falls inside the blue line segment and you have a successful 
  96. collision.  Otherwise, perform the same test with all the other endpoints.  If 
  97. any of the endpoints falls on the other line segment, then you have a 
  98. successful collision.
  99.  
  100. Optimizations:
  101.  
  102. At the beginning of this document I mentioned using bounding boxes to cut down 
  103. the number of lines to test.  Bounding box tests are cheap, and even with 50+ 
  104. objects on the screen the time spent comparing bounding boxes will probably be 
  105. completely swamped by simply drawing things on the screen.  You'll only need 
  106. something more sophisticated when you get a lot more objects on the screen.
  107.  
  108. Similarly, once you get two entire objects which satisfy the bounding box 
  109. test, you'll likely only end up with a small number of line segments which 
  110. actually need to be tested with each other.
  111.  
  112. A couple of quick optimization ideas in the calculations.  These will happen 
  113. so rarely that we probably wouldn't even notice the extra work.  But they're 
  114. so obvious I just had to mention them.
  115.  
  116. In Figure 5, where we compare the distance to each of the possible collision 
  117. points.  In this instance, we don't need to know the actual distance.  We 
  118. simply need the ranking from lowest to highest.  Therefore, we don't need to 
  119. take the square root of each of those calculations.  When it comes time to 
  120. determine the time within the frame then we will need to take the square root.
  121.  
  122. Similarly, we don't need to take the square root when determining if the 
  123. possible point of impact is on the line segment.  Compare against the square 
  124. of the length of the line segment.
  125.  
  126. Well, I think that's enough to get you started.  I'd like to throw together 
  127. some example code, but I'm completely swamped at work, so I'll leave that as 
  128. an exercise.  If anyone posts some code that's based on these ideas, please 
  129. let me know and I'll include a pointer in this document.
  130.  
  131. References:
  132.  
  133. Be sure to check out IMPACT21.ZIP by John Henckel henckel@vnet.ibm.com.  It's 
  134. available in GAMDEV on Compuserve and shows up on internet searches.  It's a 
  135. nifty polygon collision example, including source code.  He handles rotating 
  136. polygons, and momentum transfer.
  137.  
  138. Thanks to Kevin J Hoffman 102547,3560 for spurring this line of thought and 
  139. brainstorming with me. It was an interesting problem.
  140.  
  141. Drake Christensen 71251.433@compuserve.com
  142.